package com.heima.notice.configuration;


import com.alibaba.fastjson.JSON;
import com.heima.modules.po.NoticePO;
import com.heima.notice.service.NoticeService;
import com.heima.notice.socket.WebSocketServer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.websocket.Session;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * 定时任务 推送暂存消息
 */
@Component
public class ScheduledTask {

    private static final Logger logger = LoggerFactory.getLogger(ScheduledTask.class);

    @Autowired
    private NoticeService noticeService;

    private static final ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1);//Java 的定时任务工具，相当于一个 "闹钟"，可以设置每隔多久执行一次任务。这里创建了一个只有 1 个线程的线程池来运行定时任务。

    @PostConstruct
    public void init() {
        //TODO:任务5.2-推送未读消息
        //定时调度，获取mongodb里的未读消息，推送给对应用户
        executorService.scheduleAtFixedRate(() -> {
            // 获取所有在线用户accountId
            Set<String> onlineUsers = WebSocketServer.sessionPools.keySet();//获取这个 Map 里所有的 key，也就是所有在线用户的accountId（用户 ID）。

            // 获取需要推送的消息
            List<String> receiverIds = new ArrayList<>(onlineUsers);//把在线用户的 ID 转成一个列表（receiverIds，接收人 ID 列表）。
            List<NoticePO> notices = noticeService.getNoticeByAccountIds(receiverIds);//通过这个服务类，从数据库（MongoDB）中查询 "这些在线用户的未读消息"（NoticePO是消息在数据库中的实体类，包含消息内容、接收人等信息）。//找出所有在线用户的未读消息

            // 遍历所有消息，逐个发送给对应的用户
            for (NoticePO notice : notices) {
                Session session = WebSocketServer.sessionPools.get(notice.getReceiverId());//notice.getReceiverId()：获取这条消息的 "接收人 ID"（比如消息是发给用户 A 的，就拿到 A 的 accountId）。//WebSocketServer.sessionPools.get(...)：从 "在线用户通讯录"（sessionPools）中，根据接收人 ID 找到对应的连接会话（Session）。
                if (session != null && session.isOpen()) {
                    try {
                        // 把消息对象转成JSON字符串（方便网络传输）
                        String json = JSON.toJSONString(notice);
                        session.getBasicRemote().sendText(json);//通过找到的有效连接（Session），把 JSON 字符串形式的消息发给用户（相当于 "通过聊天窗口发送消息"）。
                    } catch (IOException e) {
                        e.printStackTrace();// 如果发送失败（比如突然断网），打印错误信息
                    }
                }
            }
        }, 0,1 , TimeUnit.SECONDS);//任务立即开始执行第一次，之后每隔 1 秒重复执行一次
    }

}
